package com.uestc.admin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;

import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;

import org.apache.hadoop.hbase.util.Bytes;

import com.uestc.hbase.MTable;

import com.uestc.servlet.admin.config.ReadConfig;
import com.uestc.util.JsonUtil;

public interface AdminBase {

	default public String getColumns(String columnString) {
		return ReadConfig.getItem(columnString);
	}

	public String getColumnName();

	/**
	 * 用于获取表中代表日期的列名
	 * 
	 * @return
	 */
	public String getDateColumnName();

	public String getTableName();

	default public String getColumns() {
		return ReadConfig.getItem(getColumnName());
	}

	/**
	 * 分页查看每页的内容
	 * 
	 * @param page
	 *            页码，从0开始
	 * @param limit
	 *            每页显示的信息数
	 * @param request
	 *            HttpRequest请求，用于获得Session来记录上次看到的最后一行
	 * @return
	 * @throws Throwable
	 */
	public String getInfo(int page, int limit, HttpServletRequest request) throws Throwable;

	public String getInfoWithCondition(int page, int limit, HashMap<String, String> conditions,
			HttpServletRequest request) throws Throwable;

	default public String getDetailInfo(String tableName, String configColumns, List<String> familiy, int page,
			int limit, HttpServletRequest request) throws Throwable {
		return this.getDetailInfo(tableName, configColumns, familiy, page, limit, request, null, null);
	}

	default public String getDetailInfo(String tableName, String configColumns, List<String> familiy, int page,
			int limit, HttpServletRequest request, String fam, HashMap<String, String> conditions) throws Throwable {
		return getDetailInfo(tableName, configColumns, familiy, page, limit, request, fam, conditions,
				MTable.FILTER_TYPE.SINGLE_COLUMN_VALUE_FILTER, MTable.FILTER_COMBINE.MUST_PASS_ALL);
	}

	default public String getDetailInfo(String tableName, String configColumns, List<String> familiy, int page,
			int limit, HttpServletRequest request, String fam, HashMap<String, String> conditions,
			MTable.FILTER_TYPE filterTpye) throws Throwable {
		return getDetailInfo(tableName, configColumns, familiy, page, limit, request, fam, conditions, filterTpye,
				MTable.FILTER_COMBINE.MUST_PASS_ALL);
	}

	/**
	 * 分页获取表格的数据
	 * 
	 * @param tableName
	 *            表名
	 * @param configColumns
	 *            在config.json文件中得到的列名
	 * @param familiy
	 *            列族名称组成的List，目前只有“info”一个列族
	 * @param page
	 *            页码，从0开始
	 * @param limit
	 *            每页的数目
	 * @param request
	 *            HttpServletRequest请求， 用于记录上一次查询结束的行
	 * @return
	 * @throws Throwable
	 */
	default public String getDetailInfo(String tableName, String configColumns, List<String> familiy, int page,
			int limit, HttpServletRequest request, String fam, HashMap<String, String> conditions,
			MTable.FILTER_TYPE filterTpye, MTable.FILTER_COMBINE conditionsType) throws Throwable {
		String result = null;
		MTable mTable = new MTable(tableName);
		byte[] lastRow = null; // 记录最后一行，存放在Cookie里，留着下一次用。
		String[] columns = ReadConfig.getItems(configColumns); // 前端要显示的列
		if (page > 0) {
			lastRow = (byte[]) request.getSession().getAttribute("lastRow");
		}

		LinkedHashMap<byte[], Map<String, Map<String, String>>> resultMap;
		if (fam == null || conditions == null)
			resultMap = mTable.getPage(limit, lastRow, familiy);
		else
			resultMap = mTable.getPage(limit, lastRow, familiy, fam, conditions, filterTpye, conditionsType); // 列族名，这里只有info

		// 生成JSON字符串
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("success", "true");
		if (conditions == null)
			map.put("totalProperty", mTable.getRowCounter(tableName, familiy.get(0).intern(), "username"));
		else
			map.put("totalProperty",
					mTable.getRowCounterWithConditions(tableName, familiy.get(0).intern(), conditions, conditionsType));
		List<Object> jsonArray = new ArrayList<Object>(); // 存放每一行的数据

		for (Map.Entry<byte[], Map<String, Map<String, String>>> map1 : resultMap.entrySet()) {
			--limit;
			if (limit == -1) {
				lastRow = map1.getKey();
			}

			// 这个循环暂时只有一层，因为只有一个列族info
			for (Map.Entry<String, Map<String, String>> map2 : map1.getValue().entrySet()) {
				if (map2.getKey().equals("info")) {
					HashMap<String, String> temp = new HashMap<String, String>();
					for (String column : columns) {
						String columnName = JsonUtil.getAttribute(column, "columnName");
						String hbaseName = JsonUtil.getAttribute(column, "hbase");
						// 获取每行的行健，因此列族中的列名不要为rowKey
						if ("rowKey".equals(hbaseName)) {
							temp.put(columnName, new String(map1.getKey()));
						} else {
							Map<String, String> map3 = map2.getValue();
							temp.put(columnName, map3.get(hbaseName));
						}
					}
					jsonArray.add(temp);
				}
			}
		}
		map.put("rows", jsonArray);
		result = JsonUtil.createJsonString(map);
		System.out.println(result);
		// 缓存上一个的信息
		request.getSession().setAttribute("lastRow", lastRow);
		return result;
	}

	default public LinkedHashMap<byte[], Map<String, Map<String, String>>> getInfoWithCondition(List<String> familyList,
			String fam, String beginTime, String endTime, HttpServletRequest request) {
		String tableName = this.getTableName();
		String dateColumnName = this.getDateColumnName();
		Scan scan = new Scan();
		ArrayList<Filter> filters = new ArrayList<>();
		// 设置过滤器
		Filter filter1 = new SingleColumnValueFilter(Bytes.toBytes(fam), Bytes.toBytes(dateColumnName),
				CompareFilter.CompareOp.GREATER_OR_EQUAL, Bytes.toBytes(beginTime));

		Filter filter2 = new SingleColumnValueFilter(Bytes.toBytes(fam), Bytes.toBytes(dateColumnName),
				CompareFilter.CompareOp.LESS_OR_EQUAL, Bytes.toBytes(endTime));
		filters.add(filter1);
		filters.add(filter2);
		Filter filter = new FilterList(FilterList.Operator.MUST_PASS_ALL, filters);
		scan.setFilter(filter);
		MTable mTable = null;
		ResultScanner scanner = null;
		// resultMap存放行键即key，以及行键对应的许多列族即value，value是由列族名和列族对应的qualifier以及value组成
		LinkedHashMap<byte[], Map<String, Map<String, String>>> resultMap = new LinkedHashMap<>();
		try {
			mTable = new MTable(tableName);
			scanner = mTable.getScanner(scan);
			for (Result result : scanner) {
				Map<String, Map<String, String>> familyMap = new HashMap<>();
				for (String family : familyList) {
					Map<byte[], byte[]> tempQualifierMap = result.getFamilyMap(Bytes.toBytes("info"));
					Map<String, String> qualifierMap = new HashMap<>();
					// 循环改变Map的类型
					for (Map.Entry<byte[], byte[]> item : tempQualifierMap.entrySet()) {
						qualifierMap.put(Bytes.toString(item.getKey()), Bytes.toString(item.getValue()));
					}
					familyMap.put(family, qualifierMap);
				}

				resultMap.put(result.getRow(), familyMap);

			}
			System.out.println(resultMap);

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			scanner.close();
		}
		return resultMap;

	};

}
